<?php

define('MMC_WAITING_SECONDS',       3);     //链接一个mmc服务器等待时间

function session_mmc_run($hosts, $ttl = 10, $domain = '')
{
	if(count($hosts) == 0) { return(false); }

    $GLOBALS['session_mmc_env'] = array(
        'hosts'     =>  $hosts,
        'ttl'       =>  $ttl,
        'domain'    =>  $domain
        );

    ini_set('session.use_cookies', 0);  //不让PHP自动发含session的cookie
    ini_set('session.name', C('SESSION_NAME'));

    if(!empty($_POST[C('SESSION_NAME')]))
        session_id($_POST[C('SESSION_NAME')]);
    elseif(!empty($_GET[C('SESSION_NAME')]))
        session_id($_GET[C('SESSION_NAME')]);
    elseif(!empty($_COOKIE[C('SESSION_NAME')]))
        session_id($_COOKIE[C('SESSION_NAME')]);
    elseif(!empty($_COOKIE[ 'ALI'.C('SESSION_NAME')]))
        session_id($_COOKIE['ALI'.C('SESSION_NAME')]);
    else
    {
        $GLOBALS['NEW_SESSID'] = true;
        //只在第一次用户访问时生成并发送cookie
        session_cookie_header(2592000, $domain);
    }

	if(!session_set_save_handler("session_mmc_open", "session_mmc_close", "session_mmc_read", "session_mmc_write", "session_mmc_destroy", "session_mmc_gc"))
	{
	    throw_exception(L('_SESSION_SAVE_HANDLER_FAIL'));
		return(false);
	}

	session_start();
	return(true);
}

//发送session的header
function session_cookie_header($lifetime=0,$domain=null)
{
    $_ck = array();
    if(!session_id()) session_id(md5(microtime(true)));
    $_ck[] = C('SESSION_NAME');
    $_ck[] = session_id();
    $_ck[] = time()+$lifetime;
    $_ck[] = '/';
    $_ck[] = $domain;
    setcookie($_ck[0], $_ck[1], $_ck[2], $_ck[3], $_ck[4]);
    if($domain && false===strpos($_SERVER['HTTP_HOST'], $domain))
    {
        setcookie('ALI'.$_ck[0], $_ck[1], $_ck[2], $_ck[3], 'af.com');
    }
}

function session_mmc_open($save_path, $session_name)
{
	return(true);
}

function session_mmc_close()
{
	unset($GLOBALS['session_mmc_env']);
	return(true);
}

function session_mmc_read($session_id)
{
    if(!empty($GLOBALS['NEW_SESSID']))
    {
        $GLOBALS['L_SESSION_DATA'] = null;
        return null;
    }

	$link = session_mmc_dispatch($session_id);
	if(!$link) { return(false); }

	$ret = memcache_get($link, $session_id);
    $GLOBALS['L_SESSION_DATA'] = $ret;

	return($ret);
}

function session_mmc_write($session_id, $session_data)
{
    if(strcmp($session_data,$GLOBALS['L_SESSION_DATA'])===0)
    {
        return true;
    }

	$env = &$GLOBALS['session_mmc_env'];
	$link = session_mmc_dispatch($session_id);
	if(!$link) { return(false); }

    if($session_data)
    {
	    $ret = memcache_set($link, $session_id, $session_data, 0, $env['ttl']);
    }
    elseif($GLOBALS['L_SESSION_DATA'])
    {
        $ret = memcache_delete($link, $session_id);
    }

    memcache_close($link);
	return($ret);
}

function session_mmc_destroy($session_id)
{
    if($GLOBALS['L_SESSION_DATA'])
    {
        $link = session_mmc_dispatch($session_id);
        if(!$link) { return(false); }

        $ret = memcache_delete($link, $session_id);
        memcache_close($link);
        return($ret);
    }
    return true;
}

function session_mmc_gc($session_maxlifetime)
{
	return(true);
}

function session_mmc_dispatch($session_id)
{
    static $link=null;
    if(!$link)
    {
        $env = &$GLOBALS['session_mmc_env'];
        $count = count($env['hosts']);
        if($count == 1)
        {
            $index  = 0;
        }else{
            /* load balancing */
            $index = hexdec(substr(md5($session_id), 0, 4)) % $count;
        }
        $host = &$env['hosts'][$index];
        $env["index"] = $index;
        $link = memcache_connect($host[0], $host[1], MMC_WAITING_SECONDS);
    }
	return($link);
}

function session_mmc_stats()
{
	$host = &$GLOBALS['session_mmc_env']['hosts'][$GLOBALS['session_mmc_env']['index']];
	$link = memcache_connect($host[0], $host[1], MMC_WAITING_SECONDS);
	$ret = memcache_get_stats($link);
	return('<pre>' . var_export($ret, true) . '</pre>');
}

/**
'SESSION_MMC_FLAG'   => true,
'SESSION_MMC_SERVER' => array(array('192.168.5.98', 1100),
                              array('192.168.5.97', 1100),
                              array('192.168.5.96', 1100),
                             ),
'SESSION_MMC_DOMAIN' => 'domain.com',
'SESSION_MMC_TTL'    => 3600,
'SESSION_AUTO_START' => true,
'SESSION_NAME'       => 'AVISESS',
*/
function session_mmc_start()
{
	//取得config.php配置文件 中的配置内容
    $mmc_host = C('SESSION_MMC_SERVER');
    if (empty($mmc_host)) {
    	//如果没有定义抛出异常
        throw_exception(L('_MMC_HOST_IS_EMPTY'));
    }
    //生命周期
    $mmc_ttl        = C('SESSION_MMC_TTL');
    if (!$mmc_ttl) {
        $mmc_ttl = 0;
    }
    //session域名 
    $session_domain = C('SESSION_MMC_DOMAIN');
    if (false === $session_domain) {
        $session_domain = '';
    }

    session_mmc_run($mmc_host, $mmc_ttl, $session_domain);
}


?>